//
//  File.swift
//  NetAction
//
//  Created by zcj on 2024/12/27.
//  description: 实现tcplistener的功能，由于其作为listener，所以调用Listen的需要实现几个功能：
/*  1. 对于connection的控制，包括生存周期的控制等等，
    2. 对于数据的处理是分为异步还是同步，（如果是文件等连贯的数据传输请求就需要同步）
 */
import Foundation
import Network

public protocol TCPListenDelegate:AnyObject{
    //接受connection 和 Data的功能
    func receiveConAndData(connection:NWConnection,data:Data);
    func ListenReady();
    func ListenFailed();
    
}

public class TCPListen{
    public let listener:NWListener
    public weak var delegate:TCPListenDelegate?
    //使用异步的方式返回还是同步的方式
    var state:Int32 = 0
    //串行队列,接受数据并将数据处理成为可以用的数据需要次序，这里就是
    let serialTaskQueue = DispatchQueue(label: "com.ListenerTaskSerial",qos: .utility)
    //并发队列
    let concurrentTaskQueue = DispatchQueue(label:"com.ListenerTaskConcurrent",qos:.utility,attributes: .concurrent)
    public init(port:UInt16,sta:Int32){
        let nwEndpoint = NWEndpoint.Port(rawValue: port)!
        let nwParameters = NWParameters.tcp
        self.listener = try! NWListener(using: nwParameters, on: nwEndpoint)
        state = sta
    }
    
    public init(port:UInt16,dlg:TCPListenDelegate,sta:Int32){
        let nwEndpoint = NWEndpoint.Port(rawValue: port)!
        let nwParameters = NWParameters.tcp
        self.listener = try! NWListener(using: nwParameters, on: nwEndpoint)
        delegate = dlg
        state = sta
    }
    
    public func start() {
        listener.stateUpdateHandler = stateDidChange(to:)//listener状态的控制功能
        
        listener.newConnectionHandler = didAccept(from:) //有新链接时的行动
        
        listener.start(queue: .global())
    }
    
    public func close(){
        listener.cancel()
    }
    
    private func stateDidChange(to newState: NWListener.State) {
        switch newState {
        case .ready:
            delegate?.ListenReady()
            print("Server ready.")
        case .failed(let error):
            print("Server failure, error: \(error.localizedDescription)")
            delegate?.ListenFailed()
            exit(EXIT_FAILURE)
        default:
            break
        }
    }
    
    private func didAccept(from nwConnection: NWConnection) {
        nwConnection.stateUpdateHandler = { newState in
            switch newState {
            case .ready:
                print("Connection ready.")
                self.receiveData(from: nwConnection)
                break
            case .failed(let error):
                print("Connection failure, error: \(error.localizedDescription)")
                break
            default:
                break
            }
        }
        nwConnection.start(queue: .global())
    }
    

    
    func receiveData(from connection:NWConnection){
        connection.receive(minimumIncompleteLength: 1, maximumLength: 655360) { data, _, isComplete, error in
            if let data = data, !data.isEmpty {
                //发送给delegate来执行
                if self.state == 0{
                    self.serialTaskQueue.async {
                        self.delegate?.receiveConAndData(connection: connection, data: data)
                    }
                }else{
                    self.concurrentTaskQueue.async {
                        self.delegate?.receiveConAndData(connection: connection, data: data)
                    }
                }
            }
            
            if isComplete {
                print("server Connection closed by client")
                connection.cancel()// 实际要在delegate哪里也删除
            } else if let error = error {
                print("server Failed to receive data: \(error)")
                connection.cancel()
            } else {
                self.receiveData(from: connection)
            }
        }
       
        
    }
}
